/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
/* scss */
import '@src/component/business/BizFormDialog/BizFormDialog.scss'
/* entity */
import Field from '@model/entity/Field'
/* vue */
import VC from '@model/VC'
import { Component, Emit, Prop, Ref } from 'vue-property-decorator'
import { CreateElement } from 'vue'
import i18n from '@src/locales'
/* util */
import Log from '@src/util/log.ts'
import * as FormUtil from '@src/component/form/util'

type FieldUpdateResult = {
  field: Field,
  newValue: any, 
  oldValue: any
}

enum BizFormDiaLogEmitEventNameEnum {
  Close = 'close',
  Submit = 'submit'
}

@Component({ 
  name: ComponentNameEnum.BizFormDialog
})
export default class BizFormDialog extends VC {
  
  /* 按钮文字 */
  @Prop() readonly buttonText: string | undefined
  /* 表单字段列表 */
  @Prop() readonly fields: Field[] | undefined
  /* 提交事件 */
  @Prop() readonly submitFunction: Function | undefined
  /* 标题 */
  @Prop() readonly title: string | undefined
  /* 底部提示 */
  @Prop() readonly footerTip: string | undefined
  
  /* 表单数据 */
  private form: Record<string, any> = {}

  /* 是否显示弹窗 */
  private visiableDialog: boolean = false
  
  /** 
   * @description 分发关闭事件
   * @return {Boolean}
  */
  @Emit(BizFormDiaLogEmitEventNameEnum.Close)
  private emitCloseHandler(): boolean {
    return false
  }
  
  /** 
   * @description 分发提交事件
   * @return {Record<string, any>} 表单数据
  */
  @Emit(BizFormDiaLogEmitEventNameEnum.Submit)
  private emitSubmitHandler(): Record<string, any> {
    return this.form
  }
  
  /**
   * @description 关闭
   * @return {void}
   */  
  private close(): void {
    this.emitCloseHandler()
    this.visiableDialog = false
  }
  
  /**
   * @description 获取属性列表
   * @return {Record<string, any>} 属性列表
   */  
  private getAttributes(): Record<string, any> {
    return {
      width: '700px',
      props: {
        width: '700px',
        title: this.title,
        show: this.visiableDialog
      },
      on: {
        'update:show': (value: boolean) => {
          this.visiableDialog = value
        }
      },
      directives: [
        {
          name: 'loading',
          value: this.pending
        }
      ]
    }
  }
  
  /**
   * @description: 初始化表单数据
   * @return {void}
   */  
  private initForm(): void {
    this.form = FormUtil.initialize(this.fields, {}, undefined)
  }

  /* 等待状态 */
  private pending: boolean = false
  
  /**
   * @description: 显示弹窗
   * -- 支持外部调用的
   * @return {void}
   */  
  public outsideShow(): void {
    this.show()
  }
  
  /**
   * @description: 关闭弹窗
   * -- 支持外部调用的
   * @return {void}
   */  
  public outsideClose(): void {
    this.close()
  }
  
  /**
   * @description: 显示弹窗
   * @return {void}
   */  
  private show(): void {
    this.initForm()
    this.visiableDialog = true
  }
  
  /**
   * @description: 提交事件
   * @return {void}
   */  
  private submit(): void {
    this.submitFunction && this.submitFunction(this.form)
  }
  
  /**
   * @description: 更新事件
   * @param {FieldUpdateResult} param
   * @return {void}
   */  
  private update({ field, newValue }: FieldUpdateResult): void {
    const { fieldName, displayName } = field
    
    Log.info(newValue, `[FormBuilder] ${displayName}(${fieldName})`, this.update.name)
    
    this.form[fieldName] = newValue
  }

  /**
   * @description 渲染弹窗底部
   * @return {VNode}
   */  
  private renderDialogFooter() {
    if(this.footerTip) return (
      <div slot='footer' class='dialog-footer footer-tip'>
        <div class="tip">{ this.footerTip }</div>
        <div>
          <el-button onClick={() => this.close()}>
            {i18n.t('common.base.cancel')}
          </el-button>
          <el-button
            type='primary' 
            onClick={() => this.submit()}
            disabled={this.pending}
          >
            { this.buttonText }
          </el-button>
        </div>
      </div>
    )

    return (
      <div slot='footer' class='dialog-footer'>
        <el-button onClick={() => this.close()}>
          {i18n.t('common.base.cancel')}
        </el-button>
        <el-button
          type='primary' 
          onClick={() => this.submit()}
          disabled={this.pending}
        >
          { this.buttonText }
        </el-button>
      </div>
    )
  }
  
  mounted() {
    this.initForm()
  }
  
  render(h: CreateElement) {
    const attrs = this.getAttributes()
    
    return (
      <base-modal {...attrs}>
        
        <div class='base-modal-content'>
          <form-builder 
            ref='FormComponent'
            fields={this.fields} 
            value={this.form} 
            onUpdate={(result: FieldUpdateResult) => this.update(result)}
          >
          </form-builder>
        </div>
        
        { this.renderDialogFooter() }
        
      </base-modal>
    )
  }
}

